﻿using movie.tool.library.binding;
using movie.tool.module.film.model;
using movie.tool.module.film.service;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace movie.tool.module.encode
{
    public class SceneInfo : NotifyPropertyChanged
    {
        private bool chked;
        private string encodedVideo;
        public bool Checked
        {
            get { return chked; }
            set
            {
                chked = value;
                SendPropertyChanged("Checked");
            }
        }
        public string MovieName { get; set; }
        public string SceneName { get; set; }
        public string SourceVideo { get { return MovieDir + "\\" + FilePath; } }
        public string EncodedVideo
        {
            get { return encodedVideo; }
            set
            {
                encodedVideo = value;
                SendPropertyChanged(() => EncodedVideo);
            }
        }
        /// <summary>
        /// 剧本根目录
        /// </summary>
        public string MovieDir { get; set; }
        public string FilePath { get; set; }
    }

    /// <summary>
    /// MovieEncodeWin.xaml 的交互逻辑
    /// </summary>
    public partial class MovieEncodeWin : Window, INotifyPropertyChanged
    {
        private static string key = "5C41119F6D20F157F9ACD97E5BE55055";
        private static string keyId = "04B7463160A72DCA25FA7A18413327AF";
        private static string rootDir = System.Environment.CurrentDirectory;
        public IList<SceneInfo> SceneList { get; set; }
        public IList<Movie> MovieList { get; set; }
        public MovieEncodeWin()
        {
            InitializeComponent();
        }

        public event PropertyChangedEventHandler PropertyChanged;
        /// <summary>
        /// 通过Lambda表达式发送通知消息
        /// </summary>
        /// <param name="propertyLambda">访问属性的Lambda表达式</param>
        protected void SendPropertyChanged(Expression<Func<object>> propertyLambda)
        {
            SendPropertyChanged(PropertyName.Get(propertyLambda));
        }

        /// <summary>
        /// 发送通知消息
        /// </summary>
        /// <param name="propetyName">属性名称字符串</param>
        protected void SendPropertyChanged(string propetyName)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propetyName));
            }
        }

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.MovieList = MovieService.Movies;
            SendPropertyChanged(() => MovieList);
            BuildSceneList(MovieList);
        }

        private void BuildSceneList(IEnumerable<Movie> movies)
        {
            List<SceneInfo> list = new List<SceneInfo>();
            if (movies != null && movies.Count() > 0)
            {
                foreach (Movie mv in movies)
                {
                    String movieName = mv.Name;
                    mv.Scenes.ForEach(sc => {
                        SceneInfo si = new SceneInfo();
                        si.MovieName = movieName;
                        si.SceneName = sc.Name;
                        si.EncodedVideo = "";
                        si.MovieDir = mv.Dir;
                        si.FilePath = sc.File;
                        list.Add(si);
                    });
                }
            }
            this.SceneList = list;
            SendPropertyChanged(() => SceneList);
        }

        private void EncodeVideo(object sender, RoutedEventArgs e)
        {
            new Thread(() => {
                IEnumerable<SceneInfo> list = SceneList.Where(scene => scene.Checked);
                foreach (SceneInfo scene in list)
                {
                    string path = scene.SourceVideo;
                    string outputPath = MovieDir(scene.MovieName) + "\\" + scene.FilePath;
                    DirectoryInfo di = Directory.GetParent(outputPath);
                    if (!di.Exists)
                    {
                        di.Create();
                    }

                    string arg = "-i " + path + " -y -c:v copy -c:a copy -encryption_scheme cenc-aes-ctr -encryption_key " + key
                        + " -encryption_kid " + keyId + " " + outputPath;
                    ProcessStartInfo info = new ProcessStartInfo("ffmpeg", arg);
                    info.CreateNoWindow = true;
                    Process p = Process.Start(info);
                    if (p != null)
                    {
                        p.WaitForExit();
                    }
                    scene.EncodedVideo = outputPath;
                }
            }).Start();
        }
        /// <summary>
        /// 剧本输出目录
        /// </summary>
        /// <param name="movie"></param>
        /// <returns></returns>
        private static string MovieDir(string movie)
        {
            string dir = rootDir + "\\encrypt\\" + movie;
            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
            return dir;
        }

        private void CheckBox_Checked(object sender, RoutedEventArgs e)
        {
            CheckBox ck = sender as CheckBox;
            if (ck != null)
            {
                bool ckd = ck.IsChecked != null ? (bool)ck.IsChecked : false;
                foreach (SceneInfo si in SceneList)
                {
                    si.Checked = ckd;
                }
            }
        }

        private void ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            ComboBox combo = sender as ComboBox;
            if (combo != null)
            {
                Movie movie = combo.SelectedItem as Movie;
                if (movie != null)
                {
                    List<Movie> list = new List<Movie>();
                    list.Add(movie);
                    BuildSceneList(list);
                }
            }
        }
    }
}
